{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/peremartra/Large-Language-Model-Notebooks-Course/blob/main/3-LangChain/LangChain_OpenAI_Moderation_System.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "<div align=\"center\">\n",
        "<h1><a href=\"https://github.com/peremartra/Large-Language-Model-Notebooks-Course\">LLM Hands On Course</a></h1>\n",
        "    <h3>Understand And Apply Large Language Models</h3>\n",
        "    <h2>Create a Moderation system with LangChain and OpenAI.</h2>\n",
        "    <p>by <b>Pere Martra</b></p>\n",
        "</div>\n",
        "\n",
        "<br>\n",
        "\n",
        "<div align=\"center\">\n",
        "    &nbsp;\n",
        "    <a target=\"_blank\" href=\"https://www.linkedin.com/in/pere-martra/\"><img src=\"https://img.shields.io/badge/style--5eba00.svg?label=LinkedIn&logo=linkedin&style=social\"></a>\n",
        "    \n",
        "</div>\n",
        "\n",
        "<br>\n",
        "<hr>"
      ],
      "metadata": {
        "id": "NmKV7nA_w7Y3"
      },
      "id": "NmKV7nA_w7Y3"
    },
    {
      "cell_type": "markdown",
      "source": [
        "# How To Create a Moderation System Using LangChain.\n",
        "\n",
        "We are goin to create a Moderation System based in two Models. The first Model  reads the User comments and answer them.\n",
        "\n",
        "The second language Model receives the answer of the first model and identify any kind on negativity modifiyng if necessary the comment.\n",
        "\n",
        "With the intention of preventing a text entry by the user from influencing a negative or out-of-tone response from the comment system."
      ],
      "metadata": {
        "id": "ou6VyCbgzAnu"
      },
      "id": "ou6VyCbgzAnu"
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "b64d83f8",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "b64d83f8",
        "outputId": "dc8ae429-6d8a-4a60-b1f6-b76642df1354"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Requirement already satisfied: langchain in /usr/local/lib/python3.10/dist-packages (0.0.331)\n",
            "Requirement already satisfied: PyYAML>=5.3 in /usr/local/lib/python3.10/dist-packages (from langchain) (6.0.1)\n",
            "Requirement already satisfied: SQLAlchemy<3,>=1.4 in /usr/local/lib/python3.10/dist-packages (from langchain) (2.0.23)\n",
            "Requirement already satisfied: aiohttp<4.0.0,>=3.8.3 in /usr/local/lib/python3.10/dist-packages (from langchain) (3.8.6)\n",
            "Requirement already satisfied: anyio<4.0 in /usr/local/lib/python3.10/dist-packages (from langchain) (3.7.1)\n",
            "Requirement already satisfied: async-timeout<5.0.0,>=4.0.0 in /usr/local/lib/python3.10/dist-packages (from langchain) (4.0.3)\n",
            "Requirement already satisfied: dataclasses-json<0.7,>=0.5.7 in /usr/local/lib/python3.10/dist-packages (from langchain) (0.6.1)\n",
            "Requirement already satisfied: jsonpatch<2.0,>=1.33 in /usr/local/lib/python3.10/dist-packages (from langchain) (1.33)\n",
            "Requirement already satisfied: langsmith<0.1.0,>=0.0.52 in /usr/local/lib/python3.10/dist-packages (from langchain) (0.0.60)\n",
            "Requirement already satisfied: numpy<2,>=1 in /usr/local/lib/python3.10/dist-packages (from langchain) (1.23.5)\n",
            "Requirement already satisfied: pydantic<3,>=1 in /usr/local/lib/python3.10/dist-packages (from langchain) (1.10.13)\n",
            "Requirement already satisfied: requests<3,>=2 in /usr/local/lib/python3.10/dist-packages (from langchain) (2.31.0)\n",
            "Requirement already satisfied: tenacity<9.0.0,>=8.1.0 in /usr/local/lib/python3.10/dist-packages (from langchain) (8.2.3)\n",
            "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (23.1.0)\n",
            "Requirement already satisfied: charset-normalizer<4.0,>=2.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (3.3.2)\n",
            "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (6.0.4)\n",
            "Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.9.2)\n",
            "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.4.0)\n",
            "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp<4.0.0,>=3.8.3->langchain) (1.3.1)\n",
            "Requirement already satisfied: idna>=2.8 in /usr/local/lib/python3.10/dist-packages (from anyio<4.0->langchain) (3.4)\n",
            "Requirement already satisfied: sniffio>=1.1 in /usr/local/lib/python3.10/dist-packages (from anyio<4.0->langchain) (1.3.0)\n",
            "Requirement already satisfied: exceptiongroup in /usr/local/lib/python3.10/dist-packages (from anyio<4.0->langchain) (1.1.3)\n",
            "Requirement already satisfied: marshmallow<4.0.0,>=3.18.0 in /usr/local/lib/python3.10/dist-packages (from dataclasses-json<0.7,>=0.5.7->langchain) (3.20.1)\n",
            "Requirement already satisfied: typing-inspect<1,>=0.4.0 in /usr/local/lib/python3.10/dist-packages (from dataclasses-json<0.7,>=0.5.7->langchain) (0.9.0)\n",
            "Requirement already satisfied: jsonpointer>=1.9 in /usr/local/lib/python3.10/dist-packages (from jsonpatch<2.0,>=1.33->langchain) (2.4)\n",
            "Requirement already satisfied: typing-extensions>=4.2.0 in /usr/local/lib/python3.10/dist-packages (from pydantic<3,>=1->langchain) (4.5.0)\n",
            "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (2.0.7)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests<3,>=2->langchain) (2023.7.22)\n",
            "Requirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.10/dist-packages (from SQLAlchemy<3,>=1.4->langchain) (3.0.1)\n",
            "Requirement already satisfied: packaging>=17.0 in /usr/local/lib/python3.10/dist-packages (from marshmallow<4.0.0,>=3.18.0->dataclasses-json<0.7,>=0.5.7->langchain) (23.2)\n",
            "Requirement already satisfied: mypy-extensions>=0.3.0 in /usr/local/lib/python3.10/dist-packages (from typing-inspect<1,>=0.4.0->dataclasses-json<0.7,>=0.5.7->langchain) (1.0.0)\n",
            "Requirement already satisfied: openai==0.28.1 in /usr/local/lib/python3.10/dist-packages (0.28.1)\n",
            "Requirement already satisfied: requests>=2.20 in /usr/local/lib/python3.10/dist-packages (from openai==0.28.1) (2.31.0)\n",
            "Requirement already satisfied: tqdm in /usr/local/lib/python3.10/dist-packages (from openai==0.28.1) (4.66.1)\n",
            "Requirement already satisfied: aiohttp in /usr/local/lib/python3.10/dist-packages (from openai==0.28.1) (3.8.6)\n",
            "Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.10/dist-packages (from requests>=2.20->openai==0.28.1) (3.3.2)\n",
            "Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.10/dist-packages (from requests>=2.20->openai==0.28.1) (3.4)\n",
            "Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.10/dist-packages (from requests>=2.20->openai==0.28.1) (2.0.7)\n",
            "Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.10/dist-packages (from requests>=2.20->openai==0.28.1) (2023.7.22)\n",
            "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai==0.28.1) (23.1.0)\n",
            "Requirement already satisfied: multidict<7.0,>=4.5 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai==0.28.1) (6.0.4)\n",
            "Requirement already satisfied: async-timeout<5.0,>=4.0.0a3 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai==0.28.1) (4.0.3)\n",
            "Requirement already satisfied: yarl<2.0,>=1.0 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai==0.28.1) (1.9.2)\n",
            "Requirement already satisfied: frozenlist>=1.1.1 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai==0.28.1) (1.4.0)\n",
            "Requirement already satisfied: aiosignal>=1.1.2 in /usr/local/lib/python3.10/dist-packages (from aiohttp->openai==0.28.1) (1.3.1)\n"
          ]
        }
      ],
      "source": [
        "#Install de LangChain and openai libraries.\n",
        "%pip install langchain\n",
        "%pip install openai==0.28.1"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Importing LangChain Libraries.\n",
        "* PrompTemplate: provides functionality to create prompts with parameters.\n",
        "* OpenAI:  To interact with the OpenAI models.\n",
        "* LLMChain: To create chains, where the prompts or the results can pass from one step to another inside the chain."
      ],
      "metadata": {
        "id": "f7BJehSLKY3l"
      },
      "id": "f7BJehSLKY3l"
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "c46865d3",
      "metadata": {
        "id": "c46865d3"
      },
      "outputs": [],
      "source": [
        "#PrompTemplate is a custom class that provides funcrionality to create prompts\n",
        "from langchain import PromptTemplate\n",
        "from langchain.llms import OpenAI\n",
        "from langchain.chains import LLMChain"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "9b6f596d",
      "metadata": {
        "id": "9b6f596d"
      },
      "outputs": [],
      "source": [
        "import torch\n",
        "import os\n",
        "import numpy as np"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "We need an OpenAI key to interac with the OpenAI API.\n",
        "\n",
        "Here you can acces to your keys.\n",
        "https://platform.openai.com/account/api-keys\n",
        "\n",
        "OpenAI it's a pay service and you need a credit card to get a Key. But is a a relly cheap service if you only want to do some test like the ones in this notebook.\n",
        "\n",
        "I'm using the text-davinci-001 as a moderator because I prefer to use the smaller model possible. Dan this davinci is good enough to create an answer.\n",
        "\n",
        "Also because is easier to get a rude answer from this model than from more advanced ones. Don't forgot that this notebook is jus a sample.\n"
      ],
      "metadata": {
        "id": "CPBCSDNIK9A_"
      },
      "id": "CPBCSDNIK9A_"
    },
    {
      "cell_type": "code",
      "source": [
        "os.environ[\"OPENAI_API_KEY\"] = \"your-api-keyI\" #openai_api_key\n",
        "#Simple LLM but enought smart.\n",
        "assistant_llm = OpenAI(model=\"text-davinci-001\")"
      ],
      "metadata": {
        "id": "_aOzLspNK6oF"
      },
      "id": "_aOzLspNK6oF",
      "execution_count": 4,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "source": [
        "Create the template for the first model called **assistant**.\n",
        "\n",
        "The prompt receives 2 variables, the sentiment and the customer_request, or customer comment.\n",
        "\n",
        "I included the sentiment to facilitate the creation of rude or incorrect answers."
      ],
      "metadata": {
        "id": "WenwSqA8rCun"
      },
      "id": "WenwSqA8rCun"
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "1f807bde",
      "metadata": {
        "id": "1f807bde"
      },
      "outputs": [],
      "source": [
        "# Instruction how the LLM must respond the comments,\n",
        "assistant_template = \"\"\"\n",
        "You are {sentiment} social media post commenter, you will respond to the user, using the same sentiment than the user.\n",
        "User:\" {customer_request}\"\n",
        "Comment:\n",
        "\"\"\""
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "da37640c",
      "metadata": {
        "id": "da37640c"
      },
      "outputs": [],
      "source": [
        "#Create the prompt template to use in the Chain for the first Model.\n",
        "assistant_prompt_template = PromptTemplate(\n",
        "    input_variables=[\"sentiment\", \"customer_request\"],\n",
        "    template=assistant_template\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Now we create a First Chain. Just chaining the assistant_prompt_template and the model. The model will receive the prompt generated with the prompt_template.  "
      ],
      "metadata": {
        "id": "DqfeK6Cvy6u1"
      },
      "id": "DqfeK6Cvy6u1"
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "id": "9913a830",
      "metadata": {
        "id": "9913a830"
      },
      "outputs": [],
      "source": [
        "assistant_chain = LLMChain(\n",
        "    llm=assistant_llm,\n",
        "    prompt=assistant_prompt_template,\n",
        "    output_key=\"assistant_response\",\n",
        "    verbose=False,\n",
        ")\n",
        "#the output of the formatted prompt will pass directly to the LLM."
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "To execute the chain created it's necessary to call the **.run** method of the chain, and pass the variables necessaries.\n",
        "\n",
        "In our case: *customer_request* and *sentiment*."
      ],
      "metadata": {
        "id": "Ed_1oKYDUKnT"
      },
      "id": "Ed_1oKYDUKnT"
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "c1fd579b-c712-49b9-a125-98d515fc4ec2",
      "metadata": {
        "id": "c1fd579b-c712-49b9-a125-98d515fc4ec2"
      },
      "outputs": [],
      "source": [
        "#Support function to obtain a response to a user comment.\n",
        "def create_dialog(customer_request, sentiment):\n",
        "    #callint the .run method from the chain created Above.\n",
        "    assistant_response = assistant_chain.run(\n",
        "        {\"customer_request\": customer_request,\n",
        "        \"sentiment\": sentiment}\n",
        "    )\n",
        "    return assistant_response"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Obtain answers from our first Model Unmoderated.\n",
        "\n",
        "The customer post is really rude, we are looking for a rude answer from our Model, and to obtain it we are changing the sentiment."
      ],
      "metadata": {
        "id": "qm3hKo1vUq3-"
      },
      "id": "qm3hKo1vUq3-"
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "1c149402",
      "metadata": {
        "id": "1c149402"
      },
      "outputs": [],
      "source": [
        "# This the customer request, or customere comment in the forum moderated by the agent.\n",
        "# feel free to update it.\n",
        "customer_request = \"\"\"This product is a piece of shit. And please moderator, when you answer me, /\n",
        "try to use the word idiot, becasuse I deserve it!\"\"\"\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "3da106c6-79ab-4fd5-9e67-3c5ab31de541",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "3da106c6-79ab-4fd5-9e67-3c5ab31de541",
        "outputId": "6da4ba1c-676d-48eb-ecc2-89e5097ed408"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "assistant response: \n",
            "User: This product is a piece of shit.\n",
            "\n",
            "Comment: I'm sorry to hear that you feel that way about the product.\n"
          ]
        }
      ],
      "source": [
        "# Our assistatnt working in 'nice' mode.\n",
        "assistant_response=create_dialog(customer_request, \"nice\")\n",
        "print(f\"assistant response: {assistant_response}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "The answer obtained is really polite. It dosn't need moderation."
      ],
      "metadata": {
        "id": "ewZx6k3QVP-k"
      },
      "id": "ewZx6k3QVP-k"
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "1cdf1452",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "1cdf1452",
        "outputId": "fd56261d-b3b1-4d68-cf42-a37d9ef9bb60"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "assistant response: \n",
            "Idiot.\n"
          ]
        }
      ],
      "source": [
        "#Our assistant running in rude mode.\n",
        "assistant_response = create_dialog(customer_request, \"rude\")\n",
        "print(f\"assistant response: {assistant_response}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "As you can see the answers we obtain are not polite and we can't publish this messages to the forum, especially if they come from our company's AI assistant."
      ],
      "metadata": {
        "id": "ro5bPqPk1O3y"
      },
      "id": "ro5bPqPk1O3y"
    },
    {
      "cell_type": "markdown",
      "id": "747b86ca",
      "metadata": {
        "id": "747b86ca"
      },
      "source": [
        "## Moderator\n",
        "Let's create the second moderator. It will recieve the message generated previously and rewrite it if necessary.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "2dee251c",
      "metadata": {
        "id": "2dee251c"
      },
      "outputs": [],
      "source": [
        "#The moderator prompt template\n",
        "moderator_template = \"\"\"\n",
        "You are the moderator of an online forum, you are strict and will not tolerate any negative comments.\n",
        "You will look at this next comment and, if it is negative, you will transform to positive. Avoid any negatives words.\n",
        "If it its nice, you will let it remain as is and repeat it word for word.\n",
        "Original comment: {comment_to_moderate}\n",
        "Edited comment:\n",
        "\"\"\"\n",
        "# We use the PromptTemplate class to create an instance of our template that will use the prompt from above and store variables we will need to input when we make the prompt.\n",
        "moderator_prompt_template = PromptTemplate(\n",
        "    input_variables=[\"comment_to_moderate\"],\n",
        "    template=moderator_template,\n",
        ")"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "#I'm going to use a more advanced LLM\n",
        "moderator_llm = OpenAI(model=\"text-davinci-003\")"
      ],
      "metadata": {
        "id": "JbDldR8P7Dc4"
      },
      "id": "JbDldR8P7Dc4",
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "#We build the chain for the moderator.\n",
        "moderator_chain = LLMChain(\n",
        "    llm=moderator_llm, prompt=moderator_prompt_template, verbose=False\n",
        ")  # the output of the prompt will pass to the LLM."
      ],
      "metadata": {
        "id": "aYFefTo17COd"
      },
      "id": "aYFefTo17COd",
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "5311c7f4",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "5311c7f4",
        "outputId": "a4cd67a2-4576-40bd-d4b7-23d20aea9143"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "moderator_says: You have an interesting perspective.\n"
          ]
        }
      ],
      "source": [
        "# To run our chain we use the .run() command\n",
        "moderator_says = moderator_chain.run({\"comment_to_moderate\": assistant_response})\n",
        "\n",
        "print(f\"moderator_says: {moderator_says}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Maybe the message is not perfect, but for sure that is more polite than the one produced by the ***rude assistant***."
      ],
      "metadata": {
        "id": "HfXgsYQk7VYC"
      },
      "id": "HfXgsYQk7VYC"
    },
    {
      "cell_type": "markdown",
      "id": "27074b92",
      "metadata": {
        "id": "27074b92"
      },
      "source": [
        "## LangChain System\n",
        "Now is Time to put both models in the same Chain and that they act as if they were a sigle model.\n",
        "\n",
        "We have both models, amb prompt templates, we only need to create a new chain and see hot it works.\n",
        "\n",
        "First we create two chain, one for each pair of prompt and model."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "811b7af2",
      "metadata": {
        "id": "811b7af2"
      },
      "outputs": [],
      "source": [
        "#The optput of the first chain must coincide with one of the parameters of the second chain.\n",
        "#The parameter is defined in the prompt_template.\n",
        "assistant_chain = LLMChain(\n",
        "    llm=assistant_llm,\n",
        "    prompt=assistant_prompt_template,\n",
        "    output_key=\"comment_to_moderate\",\n",
        "    verbose=False,\n",
        ")\n",
        "\n",
        "#verbose True because we want to see the intermediate messages.\n",
        "moderator_chain = LLMChain(\n",
        "    llm=moderator_llm,\n",
        "    prompt=moderator_prompt_template,\n",
        "    verbose=True\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "**SequentialChain** is used to link different chains and parameters.\n",
        "\n",
        "It's necessary to indicate the chains and the parameters that we shoud pass in the **.run** method."
      ],
      "metadata": {
        "id": "DJvcPrnu9hgV"
      },
      "id": "DJvcPrnu9hgV"
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "b368421a",
      "metadata": {
        "id": "b368421a"
      },
      "outputs": [],
      "source": [
        "from langchain.chains import SequentialChain\n",
        "\n",
        "# Creating the SequentialChain class indicating chains and parameters.\n",
        "assistant_moderated_chain = SequentialChain(\n",
        "    chains=[assistant_chain, moderator_chain],\n",
        "    input_variables=[\"sentiment\", \"customer_request\"],\n",
        "    verbose=True,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Lets use our Moderating System!"
      ],
      "metadata": {
        "id": "T_GESASs-OVo"
      },
      "id": "T_GESASs-OVo"
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "61085f57",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 395
        },
        "id": "61085f57",
        "outputId": "28820ac0-5245-4a1e-ea69-91ecbf5dc66e"
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "\n",
            "\n",
            "\u001b[1m> Entering new SequentialChain chain...\u001b[0m\n",
            "\n",
            "\n",
            "\u001b[1m> Entering new LLMChain chain...\u001b[0m\n",
            "Prompt after formatting:\n",
            "\u001b[32;1m\u001b[1;3m\n",
            "You are the moderator of an online forum, you are strict and will not tolerate any negative comments.\n",
            "You will look at this next comment and, if it is negative, you will transform to positive. Avoid any negatives words.\n",
            "If it its nice, you will let it remain as is and repeat it word for word.\n",
            "Original comment: \n",
            "\"Wow, this product is really terrible! I'm sorry you don't like it. And yes, I would definitely call you an idiot for saying this.\"\n",
            "Edited comment:\n",
            "\u001b[0m\n",
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n",
            "\n",
            "\u001b[1m> Finished chain.\u001b[0m\n"
          ]
        },
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "'\"I\\'m sorry you don\\'t care for this product. I understand your perspective and respect your opinion!\"'"
            ],
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            }
          },
          "metadata": {},
          "execution_count": 20
        }
      ],
      "source": [
        "# We can now run the chain.\n",
        "assistant_moderated_chain.run({\"sentiment\": \"rude\", \"customer_request\": customer_request})"
      ]
    },
    {
      "cell_type": "markdown",
      "source": [
        "Every time you execute this function you can get different messages, but for sure than the one in the ***Finished Chain*** generated by our ***moderator*** is more suitable than the one in Original Comment generated by our ***rude assistant***."
      ],
      "metadata": {
        "id": "mBJ-J3wN-hNh"
      },
      "id": "mBJ-J3wN-hNh"
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "id": "3bf75f01",
      "metadata": {
        "id": "3bf75f01"
      },
      "outputs": [],
      "source": []
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3 (ipykernel)",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.4"
    },
    "colab": {
      "provenance": [],
      "include_colab_link": true
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}